library(tidyverse)
library(readxl)
library(janitor)
library(here)
library(assertr)

candy_2015 <- read_xlsx("raw_data/boing-boing-candy-2015.xlsx") %>%
  clean_names()
candy_2016 <- read_xlsx("raw_data/boing-boing-candy-2016.xlsx") %>%
  clean_names()
candy_2017 <- read_xlsx("raw_data/boing-boing-candy-2017.xlsx") %>%
  clean_names()
New names:

candy_2015
candy_2016
candy_2017
NA
NA

names_2015 <- names(candy_2015)
names_2016 <- names(candy_2016)
names_2017 <- names(candy_2017)

Clean 2015 data


candy_cleaned_2015 <- candy_2015 %>% 
  rename(age = how_old_are_you, 
         going_out = are_you_going_actually_going_trick_or_treating_yourself) %>% 
  mutate(year = str_extract(timestamp, '[0-9]{1,4}'), .after = timestamp) %>%
  mutate(id = row_number(timestamp) + 1e6) %>% 
  mutate(gender = NA_character_, .after = age) %>% 
  mutate(country = NA_character_, .after = age) %>% 
  #mutate(is_going_out = ifelse(is_going_out == "Yes",T, F)) %>% 
  select(id, year:york_peppermint_patties, necco_wafers) %>% 
  # replace all non integer age inputs as NA, convert values to integers
  mutate(age = as.integer(age), year = as.integer(year)) %>% 
  pivot_longer(butterfinger:necco_wafers, names_to = "candy_name", values_to = "rating") %>% 
  select(id, year, going_out, age, gender, country, candy_name, rating)
Warning: NAs introduced by coercionWarning: NAs introduced by coercion to integer range
# maybe pivot_longer for combining three datasets
candy_cleaned_2015

Clean 2016 data


candy_cleaned_2016 <- candy_2016 %>% 
  rename(going_out = are_you_going_actually_going_trick_or_treating_yourself,
         age = how_old_are_you,
         country = which_country_do_you_live_in,
         gender = your_gender) %>%
  mutate(id = row_number(timestamp) + 2e6, .before = timestamp) %>% 
  mutate(year = str_extract(timestamp, '[0-9]{1,4}'), .after = timestamp) %>%
  clean_country_names() %>% 
  select(id, year:york_peppermint_patties, gender, -which_state_province_county_do_you_live_in) %>% 
  # replace all non integer age inputs as NA, convert values to integers
  mutate(age = as.integer(age), year = as.integer(year)) %>%
  pivot_longer(x100_grand_bar:york_peppermint_patties, names_to = "candy_name", values_to = "rating") %>% 
  select(id, year, going_out, age, gender, country, candy_name, rating)
Warning: NAs introduced by coercionWarning: NAs introduced by coercion to integer range
candy_cleaned_2016
NA

candy_cleaned_2017 <- candy_2017 %>% 
  rename(id = internal_id) %>% 
  pivot_longer(q1_going_out:q11_day, names_to = "col_names", values_to = "value") %>%
  select(id, col_names, value) %>%
  mutate(col_names = str_remove(col_names, "q[0-9]_")) %>%
  pivot_wider(names_from = col_names, values_from = value) %>%
  clean_names() %>%
  mutate(year = as.integer(2017), .after = id) %>%
  mutate(age = as.integer(age)) %>%
  clean_country_names() %>% 
  pivot_longer(x100_grand_bar:york_peppermint_patties, names_to = "candy_name", values_to = "rating") %>% 
  select(id, year, going_out, age, gender, country, candy_name, rating) %>% 
  filter(!is.na(rating))
Warning: NAs introduced by coercion
candy_cleaned_2017
NA

clean_country_names <- function(dataframe){
  
us_list <- c("merica", "ahemamerca", "alaska", "america","california","murica",
             "murrika","newjersey","newyork","northcarolina","pittsburgh",
             "trumpistan", "unhingedstates", "uniedstates","unitestates",
             "unitesstates", "uniteds", "us", "theunitedstates",
             "theunitedstatesofamerica", "unitedsates", "unitedstaes",
             "ipretendtobefromcanada,butiamreallyfromtheunitedstates",
             "unitedstate", "unitedstatea", "unitedstated", "usofa", "ussa",
             "ud", "USA", "sub-canadiannorthamericamerica",
             "theyooessofaaayyyyyy", "unitsstates")

uk_list <- c("endland", "england", "scotland", "uk", "unitedkingdom",
             "unitedkindom")

canada_list <- c("can", "canada")

exclude_list <- c("a", "canae", "cascadia", "earth", "fearandloathing",
                  "idontknowanymore", "insanitylately", "namerica", "narnia",
                  "sovietcanuckistan", "subscribetodmuzonyoutube", "denial",
                  "godscountry", "neverland", "oneofthebestones", "seeabove",
                  "somewhere", "eua", "thereisntoneforoldmen",
                  "therepublicofcascadia", "thisone")
  
  dataframe %>%
    mutate(country = str_remove_all(country, "[0-9]*"),
         country = str_to_lower(country),
         country = str_remove_all(country, "[`.' !?0-9]"),
         country = if_else(str_detect(country, "uniteds"),"USA", country),
         country = if_else(str_detect(country, "usa"),"USA", country)) %>% 
    mutate(country = case_when(
      country %in% us_list ~ "USA",
      country %in% uk_list ~ "UK",
      country %in% canada_list ~ "Canada",
      country %in% exclude_list ~ NA_character_,
      !is.na(country) & country != "" ~ "Other"
      ), .after = country)
}

Bind tables together


combined_data_long <- candy_cleaned_2015 %>% 
  bind_rows(candy_cleaned_2016) %>% 
  bind_rows(candy_cleaned_2017) %>% 
  mutate(candy_name = case_when(
    candy_name == "bonkers_the_candy" ~ "bonkers",
    candy_name == "boxo_raisins" ~ "box_o_raisins",
    candy_name %in% "anonymous_brown_globs_that_come_in_black_and_orange_wrappers" ~ "mary_jane",
    TRUE ~ candy_name
    )) %>% 
  filter(!candy_name %in% not_candy) %>% 
  mutate(age = if_else((age > 0 & age < 100), age, NA_integer_)) %>% 
  filter(!is.na(rating))

combined_data_long

combined_data_wide <- combined_data_long %>%
  pivot_wider(names_from = candy_name, values_from = rating)
combined_data_wide
NA

not_candy <- c("Bonkers (the board game)",
               "Anonymous brown globs that come in black and orange wrappers\t(a.k.a. Mary Janes)",
               "Any full-sized candy bar",
               "Candy that is clearly just the stuff given out for free at restaurants",
               "Cash, or other forms of legal tender",
               "Chardonnay",
               "Chick-o-Sticks (we don’t know what that is)",
               "Creepy Religious comics/Chick Tracts",
               "Dental paraphernalia",
               "Generic Brand Acetaminophen",
               "Glow sticks",
               "Gum from baseball cards",
               "Healthy Fruit",
               "Hugs (actual physical hugs)",
               "Jolly Rancher (bad flavor)",
               "Jolly Ranchers (good flavor)",
               "JoyJoy (Mit Iodine!)",
               "Senior Mints",
               "Kale smoothie",
               "Minibags of chips",
               "Real Housewives of Orange County Season 9 Blue-Ray",
               "Sandwich-sized bags filled with BooBerry Crunch",
               "Spotted Dick",
               "Those odd marshmallow circus peanut things",
               "Vials of pure high fructose corn syrup, for main-lining into your vein",
               "Vicodin",
               "White Bread",
               "Whole Wheat anything",
               "abstained_from_m_ming",
               "anonymous_brown_globs_that_come_in_black_and_orange_wrappers",
               "broken_glow_stick",
               "dental_paraphenalia",
               "lapel_pins",
               "mint_leaves",
               "person_of_interest_season_3_dvd_box_set_not_including_disc_4_with_hilarious_outtakes",
               "peterson_brand_sidewalk_chalk") %>%
  make_clean_names()

Analysis questions What is the total number of candy ratings given across the three years. (Number of candy ratings, not the number of raters. Don’t count missing values) #just a list of all the candy ratings

combined_data_long
Error: object 'combined_data_long' not found

What was the average age of people who are going out trick or treating? # age column


combined_data_wide %>% 
  filter(going_out == "Yes") %>% 
  summarise(avg_age = mean(age, na.rm = TRUE))
NA

What was the average age of people who are not going trick or treating? # age column


combined_data_wide %>% 
  filter(going_out == "No") %>% 
  summarise(avg_age = mean(age, na.rm = TRUE))
NA
NA

For each of joy, despair and meh, which candy bar received the most of these ratings? # candy ratings


combined_data_long %>%
  group_by(rating, candy_name) %>% 
  summarise(count = n()) %>% 
  slice_max(count) 
`summarise()` has grouped output by 'rating'. You can override using the `.groups` argument.

How many people rated Starburst as despair? # starburst column (candy columns)


combined_data_long %>% 
  filter(candy_name == "starburst", rating == "DESPAIR") %>% 
  summarise(count = n())
NA
NA

For the next three questions, count despair as -1, joy as +1, and meh as 0.

What was the most popular candy bar by this rating system for each gender in the dataset ? # candy ratings, gender


candy_scored <- combined_data_long %>% 
  mutate(score = case_when(
    rating == "JOY" ~ 1,
    rating == "DESPAIR" ~ -1,
    TRUE ~ 0
  ))

candy_scored %>%
  filter(!is.na(gender)) %>% 
  group_by(gender, candy_name) %>%
  summarise(total_score = sum(score)) %>% 
  slice_max(total_score)
`summarise()` has grouped output by 'gender'. You can override using the `.groups` argument.
NA
NA

What was the most popular candy bar in each year? # date or year


candy_scored %>% 
  group_by(year, candy_name) %>% 
  summarise(total_score = sum(score)) %>% 
  slice_max(total_score)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.

What was the most popular candy bar by this rating for people in US, Canada, UK, and all other countries? # countries


candy_scored %>%
  filter(country == c("USA", "Canada", "UK", "Other")) %>% 
  group_by(country, candy_name) %>% 
  summarise(total_score = sum(score)) %>% 
  slice_max(total_score)
`summarise()` has grouped output by 'country'. You can override using the `.groups` argument.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkoaGVyZSkNCmxpYnJhcnkoYXNzZXJ0cikNCg0KYGBgDQoNCmBgYHtyfQ0KDQpjYW5keV8yMDE1IDwtIHJlYWRfeGxzeCgicmF3X2RhdGEvYm9pbmctYm9pbmctY2FuZHktMjAxNS54bHN4IikgJT4lDQogIGNsZWFuX25hbWVzKCkNCmNhbmR5XzIwMTYgPC0gcmVhZF94bHN4KCJyYXdfZGF0YS9ib2luZy1ib2luZy1jYW5keS0yMDE2Lnhsc3giKSAlPiUNCiAgY2xlYW5fbmFtZXMoKQ0KY2FuZHlfMjAxNyA8LSByZWFkX3hsc3goInJhd19kYXRhL2JvaW5nLWJvaW5nLWNhbmR5LTIwMTcueGxzeCIpICU+JQ0KICBjbGVhbl9uYW1lcygpDQoNCmBgYA0KDQpgYGB7cn0NCg0KY2FuZHlfMjAxNQ0KY2FuZHlfMjAxNg0KY2FuZHlfMjAxNw0KDQoNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCg0KbmFtZXNfMjAxNSA8LSBuYW1lcyhjYW5keV8yMDE1KQ0KbmFtZXNfMjAxNiA8LSBuYW1lcyhjYW5keV8yMDE2KQ0KbmFtZXNfMjAxNyA8LSBuYW1lcyhjYW5keV8yMDE3KQ0KDQpgYGANCg0KIyMjIENsZWFuIDIwMTUgZGF0YQ0KDQpgYGB7cn0NCg0KY2FuZHlfY2xlYW5lZF8yMDE1IDwtIGNhbmR5XzIwMTUgJT4lIA0KICByZW5hbWUoYWdlID0gaG93X29sZF9hcmVfeW91LCANCiAgICAgICAgIGdvaW5nX291dCA9IGFyZV95b3VfZ29pbmdfYWN0dWFsbHlfZ29pbmdfdHJpY2tfb3JfdHJlYXRpbmdfeW91cnNlbGYpICU+JSANCiAgbXV0YXRlKHllYXIgPSBzdHJfZXh0cmFjdCh0aW1lc3RhbXAsICdbMC05XXsxLDR9JyksIC5hZnRlciA9IHRpbWVzdGFtcCkgJT4lDQogIG11dGF0ZShpZCA9IHJvd19udW1iZXIodGltZXN0YW1wKSArIDFlNikgJT4lIA0KICBtdXRhdGUoZ2VuZGVyID0gTkFfY2hhcmFjdGVyXywgLmFmdGVyID0gYWdlKSAlPiUgDQogIG11dGF0ZShjb3VudHJ5ID0gTkFfY2hhcmFjdGVyXywgLmFmdGVyID0gYWdlKSAlPiUgDQogICNtdXRhdGUoaXNfZ29pbmdfb3V0ID0gaWZlbHNlKGlzX2dvaW5nX291dCA9PSAiWWVzIixULCBGKSkgJT4lIA0KICBzZWxlY3QoaWQsIHllYXI6eW9ya19wZXBwZXJtaW50X3BhdHRpZXMsIG5lY2NvX3dhZmVycykgJT4lIA0KICAjIHJlcGxhY2UgYWxsIG5vbiBpbnRlZ2VyIGFnZSBpbnB1dHMgYXMgTkEsIGNvbnZlcnQgdmFsdWVzIHRvIGludGVnZXJzDQogIG11dGF0ZShhZ2UgPSBhcy5pbnRlZ2VyKGFnZSksIHllYXIgPSBhcy5pbnRlZ2VyKHllYXIpKSAlPiUgDQogIHBpdm90X2xvbmdlcihidXR0ZXJmaW5nZXI6bmVjY29fd2FmZXJzLCBuYW1lc190byA9ICJjYW5keV9uYW1lIiwgdmFsdWVzX3RvID0gInJhdGluZyIpICU+JSANCiAgc2VsZWN0KGlkLCB5ZWFyLCBnb2luZ19vdXQsIGFnZSwgZ2VuZGVyLCBjb3VudHJ5LCBjYW5keV9uYW1lLCByYXRpbmcpDQoNCg0KIyBtYXliZSBwaXZvdF9sb25nZXIgZm9yIGNvbWJpbmluZyB0aHJlZSBkYXRhc2V0cw0KY2FuZHlfY2xlYW5lZF8yMDE1DQpgYGANCg0KIyMjIENsZWFuIDIwMTYgZGF0YQ0KDQpgYGB7cn0NCg0KY2FuZHlfY2xlYW5lZF8yMDE2IDwtIGNhbmR5XzIwMTYgJT4lIA0KICByZW5hbWUoZ29pbmdfb3V0ID0gYXJlX3lvdV9nb2luZ19hY3R1YWxseV9nb2luZ190cmlja19vcl90cmVhdGluZ195b3Vyc2VsZiwNCiAgICAgICAgIGFnZSA9IGhvd19vbGRfYXJlX3lvdSwNCiAgICAgICAgIGNvdW50cnkgPSB3aGljaF9jb3VudHJ5X2RvX3lvdV9saXZlX2luLA0KICAgICAgICAgZ2VuZGVyID0geW91cl9nZW5kZXIpICU+JQ0KICBtdXRhdGUoaWQgPSByb3dfbnVtYmVyKHRpbWVzdGFtcCkgKyAyZTYsIC5iZWZvcmUgPSB0aW1lc3RhbXApICU+JSANCiAgbXV0YXRlKHllYXIgPSBzdHJfZXh0cmFjdCh0aW1lc3RhbXAsICdbMC05XXsxLDR9JyksIC5hZnRlciA9IHRpbWVzdGFtcCkgJT4lDQogIGNsZWFuX2NvdW50cnlfbmFtZXMoKSAlPiUgDQogIHNlbGVjdChpZCwgeWVhcjp5b3JrX3BlcHBlcm1pbnRfcGF0dGllcywgZ2VuZGVyLCAtd2hpY2hfc3RhdGVfcHJvdmluY2VfY291bnR5X2RvX3lvdV9saXZlX2luKSAlPiUgDQogICMgcmVwbGFjZSBhbGwgbm9uIGludGVnZXIgYWdlIGlucHV0cyBhcyBOQSwgY29udmVydCB2YWx1ZXMgdG8gaW50ZWdlcnMNCiAgbXV0YXRlKGFnZSA9IGFzLmludGVnZXIoYWdlKSwgeWVhciA9IGFzLmludGVnZXIoeWVhcikpICU+JQ0KICBwaXZvdF9sb25nZXIoeDEwMF9ncmFuZF9iYXI6eW9ya19wZXBwZXJtaW50X3BhdHRpZXMsIG5hbWVzX3RvID0gImNhbmR5X25hbWUiLCB2YWx1ZXNfdG8gPSAicmF0aW5nIikgJT4lIA0KICBzZWxlY3QoaWQsIHllYXIsIGdvaW5nX291dCwgYWdlLCBnZW5kZXIsIGNvdW50cnksIGNhbmR5X25hbWUsIHJhdGluZykNCg0KDQpjYW5keV9jbGVhbmVkXzIwMTYNCg0KYGBgDQoNCmBgYHtyfQ0KDQpjYW5keV9jbGVhbmVkXzIwMTcgPC0gY2FuZHlfMjAxNyAlPiUgDQogIHJlbmFtZShpZCA9IGludGVybmFsX2lkKSAlPiUgDQogIHBpdm90X2xvbmdlcihxMV9nb2luZ19vdXQ6cTExX2RheSwgbmFtZXNfdG8gPSAiY29sX25hbWVzIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lDQogIHNlbGVjdChpZCwgY29sX25hbWVzLCB2YWx1ZSkgJT4lDQogIG11dGF0ZShjb2xfbmFtZXMgPSBzdHJfcmVtb3ZlKGNvbF9uYW1lcywgInFbMC05XV8iKSkgJT4lDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjb2xfbmFtZXMsIHZhbHVlc19mcm9tID0gdmFsdWUpICU+JQ0KICBjbGVhbl9uYW1lcygpICU+JQ0KICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoMjAxNyksIC5hZnRlciA9IGlkKSAlPiUNCiAgbXV0YXRlKGFnZSA9IGFzLmludGVnZXIoYWdlKSkgJT4lDQogIGNsZWFuX2NvdW50cnlfbmFtZXMoKSAlPiUgDQogIHBpdm90X2xvbmdlcih4MTAwX2dyYW5kX2Jhcjp5b3JrX3BlcHBlcm1pbnRfcGF0dGllcywgbmFtZXNfdG8gPSAiY2FuZHlfbmFtZSIsIHZhbHVlc190byA9ICJyYXRpbmciKSAlPiUgDQogIHNlbGVjdChpZCwgeWVhciwgZ29pbmdfb3V0LCBhZ2UsIGdlbmRlciwgY291bnRyeSwgY2FuZHlfbmFtZSwgcmF0aW5nKSAlPiUgDQogIGZpbHRlcighaXMubmEocmF0aW5nKSkNCg0KY2FuZHlfY2xlYW5lZF8yMDE3DQoNCmBgYA0KDQpgYGB7cn0NCg0KY2xlYW5fY291bnRyeV9uYW1lcyA8LSBmdW5jdGlvbihkYXRhZnJhbWUpew0KICANCnVzX2xpc3QgPC0gYygibWVyaWNhIiwgImFoZW1hbWVyY2EiLCAiYWxhc2thIiwgImFtZXJpY2EiLCJjYWxpZm9ybmlhIiwibXVyaWNhIiwNCiAgICAgICAgICAgICAibXVycmlrYSIsIm5ld2plcnNleSIsIm5ld3lvcmsiLCJub3J0aGNhcm9saW5hIiwicGl0dHNidXJnaCIsDQogICAgICAgICAgICAgInRydW1waXN0YW4iLCAidW5oaW5nZWRzdGF0ZXMiLCAidW5pZWRzdGF0ZXMiLCJ1bml0ZXN0YXRlcyIsDQogICAgICAgICAgICAgInVuaXRlc3N0YXRlcyIsICJ1bml0ZWRzIiwgInVzIiwgInRoZXVuaXRlZHN0YXRlcyIsDQogICAgICAgICAgICAgInRoZXVuaXRlZHN0YXRlc29mYW1lcmljYSIsICJ1bml0ZWRzYXRlcyIsICJ1bml0ZWRzdGFlcyIsDQogICAgICAgICAgICAgImlwcmV0ZW5kdG9iZWZyb21jYW5hZGEsYnV0aWFtcmVhbGx5ZnJvbXRoZXVuaXRlZHN0YXRlcyIsDQogICAgICAgICAgICAgInVuaXRlZHN0YXRlIiwgInVuaXRlZHN0YXRlYSIsICJ1bml0ZWRzdGF0ZWQiLCAidXNvZmEiLCAidXNzYSIsDQogICAgICAgICAgICAgInVkIiwgIlVTQSIsICJzdWItY2FuYWRpYW5ub3J0aGFtZXJpY2FtZXJpY2EiLA0KICAgICAgICAgICAgICJ0aGV5b29lc3NvZmFhYXl5eXl5eSIsICJ1bml0c3N0YXRlcyIpDQoNCnVrX2xpc3QgPC0gYygiZW5kbGFuZCIsICJlbmdsYW5kIiwgInNjb3RsYW5kIiwgInVrIiwgInVuaXRlZGtpbmdkb20iLA0KICAgICAgICAgICAgICJ1bml0ZWRraW5kb20iKQ0KDQpjYW5hZGFfbGlzdCA8LSBjKCJjYW4iLCAiY2FuYWRhIikNCg0KZXhjbHVkZV9saXN0IDwtIGMoImEiLCAiY2FuYWUiLCAiY2FzY2FkaWEiLCAiZWFydGgiLCAiZmVhcmFuZGxvYXRoaW5nIiwNCiAgICAgICAgICAgICAgICAgICJpZG9udGtub3dhbnltb3JlIiwgImluc2FuaXR5bGF0ZWx5IiwgIm5hbWVyaWNhIiwgIm5hcm5pYSIsDQogICAgICAgICAgICAgICAgICAic292aWV0Y2FudWNraXN0YW4iLCAic3Vic2NyaWJldG9kbXV6b255b3V0dWJlIiwgImRlbmlhbCIsDQogICAgICAgICAgICAgICAgICAiZ29kc2NvdW50cnkiLCAibmV2ZXJsYW5kIiwgIm9uZW9mdGhlYmVzdG9uZXMiLCAic2VlYWJvdmUiLA0KICAgICAgICAgICAgICAgICAgInNvbWV3aGVyZSIsICJldWEiLCAidGhlcmVpc250b25lZm9yb2xkbWVuIiwNCiAgICAgICAgICAgICAgICAgICJ0aGVyZXB1YmxpY29mY2FzY2FkaWEiLCAidGhpc29uZSIpDQogIA0KICBkYXRhZnJhbWUgJT4lDQogICAgbXV0YXRlKGNvdW50cnkgPSBzdHJfcmVtb3ZlX2FsbChjb3VudHJ5LCAiWzAtOV0qIiksDQogICAgICAgICBjb3VudHJ5ID0gc3RyX3RvX2xvd2VyKGNvdW50cnkpLA0KICAgICAgICAgY291bnRyeSA9IHN0cl9yZW1vdmVfYWxsKGNvdW50cnksICJbYC4nICE/MC05XSIpLA0KICAgICAgICAgY291bnRyeSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb3VudHJ5LCAidW5pdGVkcyIpLCJVU0EiLCBjb3VudHJ5KSwNCiAgICAgICAgIGNvdW50cnkgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY291bnRyeSwgInVzYSIpLCJVU0EiLCBjb3VudHJ5KSkgJT4lIA0KICAgIG11dGF0ZShjb3VudHJ5ID0gY2FzZV93aGVuKA0KICAgICAgY291bnRyeSAlaW4lIHVzX2xpc3QgfiAiVVNBIiwNCiAgICAgIGNvdW50cnkgJWluJSB1a19saXN0IH4gIlVLIiwNCiAgICAgIGNvdW50cnkgJWluJSBjYW5hZGFfbGlzdCB+ICJDYW5hZGEiLA0KICAgICAgY291bnRyeSAlaW4lIGV4Y2x1ZGVfbGlzdCB+IE5BX2NoYXJhY3Rlcl8sDQogICAgICAhaXMubmEoY291bnRyeSkgJiBjb3VudHJ5ICE9ICIiIH4gIk90aGVyIg0KICAgICAgKSwgLmFmdGVyID0gY291bnRyeSkNCn0NCg0KDQpgYGANCg0KIyBCaW5kIHRhYmxlcyB0b2dldGhlcg0KDQpgYGB7cn0NCg0KY29tYmluZWRfZGF0YV9sb25nIDwtIGNhbmR5X2NsZWFuZWRfMjAxNSAlPiUgDQogIGJpbmRfcm93cyhjYW5keV9jbGVhbmVkXzIwMTYpICU+JSANCiAgYmluZF9yb3dzKGNhbmR5X2NsZWFuZWRfMjAxNykgJT4lIA0KICBtdXRhdGUoY2FuZHlfbmFtZSA9IGNhc2Vfd2hlbigNCiAgICBjYW5keV9uYW1lID09ICJib25rZXJzX3RoZV9jYW5keSIgfiAiYm9ua2VycyIsDQogICAgY2FuZHlfbmFtZSA9PSAiYm94b19yYWlzaW5zIiB+ICJib3hfb19yYWlzaW5zIiwNCiAgICBjYW5keV9uYW1lICVpbiUgImFub255bW91c19icm93bl9nbG9ic190aGF0X2NvbWVfaW5fYmxhY2tfYW5kX29yYW5nZV93cmFwcGVycyIgfiAibWFyeV9qYW5lIiwNCiAgICBUUlVFIH4gY2FuZHlfbmFtZQ0KICAgICkpICU+JSANCiAgZmlsdGVyKCFjYW5keV9uYW1lICVpbiUgbm90X2NhbmR5KSAlPiUgDQogIG11dGF0ZShhZ2UgPSBpZl9lbHNlKChhZ2UgPiAwICYgYWdlIDwgMTAwKSwgYWdlLCBOQV9pbnRlZ2VyXykpICU+JSANCiAgZmlsdGVyKCFpcy5uYShyYXRpbmcpKQ0KDQpjb21iaW5lZF9kYXRhX2xvbmcNCg0KY29tYmluZWRfZGF0YV93aWRlIDwtIGNvbWJpbmVkX2RhdGFfbG9uZyAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGNhbmR5X25hbWUsIHZhbHVlc19mcm9tID0gcmF0aW5nKQ0KY29tYmluZWRfZGF0YV93aWRlDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyfQ0KDQpub3RfY2FuZHkgPC0gYygiQm9ua2VycyAodGhlIGJvYXJkIGdhbWUpIiwNCiAgICAgICAgICAgICAgICJBbm9ueW1vdXMgYnJvd24gZ2xvYnMgdGhhdCBjb21lIGluIGJsYWNrIGFuZCBvcmFuZ2Ugd3JhcHBlcnNcdChhLmsuYS4gTWFyeSBKYW5lcykiLA0KICAgICAgICAgICAgICAgIkFueSBmdWxsLXNpemVkIGNhbmR5IGJhciIsDQogICAgICAgICAgICAgICAiQ2FuZHkgdGhhdCBpcyBjbGVhcmx5IGp1c3QgdGhlIHN0dWZmIGdpdmVuIG91dCBmb3IgZnJlZSBhdCByZXN0YXVyYW50cyIsDQogICAgICAgICAgICAgICAiQ2FzaCwgb3Igb3RoZXIgZm9ybXMgb2YgbGVnYWwgdGVuZGVyIiwNCiAgICAgICAgICAgICAgICJDaGFyZG9ubmF5IiwNCiAgICAgICAgICAgICAgICJDaGljay1vLVN0aWNrcyAod2UgZG9u4oCZdCBrbm93IHdoYXQgdGhhdCBpcykiLA0KICAgICAgICAgICAgICAgIkNyZWVweSBSZWxpZ2lvdXMgY29taWNzL0NoaWNrIFRyYWN0cyIsDQogICAgICAgICAgICAgICAiRGVudGFsIHBhcmFwaGVybmFsaWEiLA0KICAgICAgICAgICAgICAgIkdlbmVyaWMgQnJhbmQgQWNldGFtaW5vcGhlbiIsDQogICAgICAgICAgICAgICAiR2xvdyBzdGlja3MiLA0KICAgICAgICAgICAgICAgIkd1bSBmcm9tIGJhc2ViYWxsIGNhcmRzIiwNCiAgICAgICAgICAgICAgICJIZWFsdGh5IEZydWl0IiwNCiAgICAgICAgICAgICAgICJIdWdzIChhY3R1YWwgcGh5c2ljYWwgaHVncykiLA0KICAgICAgICAgICAgICAgIkpvbGx5IFJhbmNoZXIgKGJhZCBmbGF2b3IpIiwNCiAgICAgICAgICAgICAgICJKb2xseSBSYW5jaGVycyAoZ29vZCBmbGF2b3IpIiwNCiAgICAgICAgICAgICAgICJKb3lKb3kgKE1pdCBJb2RpbmUhKSIsDQogICAgICAgICAgICAgICAiU2VuaW9yIE1pbnRzIiwNCiAgICAgICAgICAgICAgICJLYWxlIHNtb290aGllIiwNCiAgICAgICAgICAgICAgICJNaW5pYmFncyBvZiBjaGlwcyIsDQogICAgICAgICAgICAgICAiUmVhbCBIb3VzZXdpdmVzIG9mIE9yYW5nZSBDb3VudHkgU2Vhc29uIDkgQmx1ZS1SYXkiLA0KICAgICAgICAgICAgICAgIlNhbmR3aWNoLXNpemVkIGJhZ3MgZmlsbGVkIHdpdGggQm9vQmVycnkgQ3J1bmNoIiwNCiAgICAgICAgICAgICAgICJTcG90dGVkIERpY2siLA0KICAgICAgICAgICAgICAgIlRob3NlIG9kZCBtYXJzaG1hbGxvdyBjaXJjdXMgcGVhbnV0IHRoaW5ncyIsDQogICAgICAgICAgICAgICAiVmlhbHMgb2YgcHVyZSBoaWdoIGZydWN0b3NlIGNvcm4gc3lydXAsIGZvciBtYWluLWxpbmluZyBpbnRvIHlvdXIgdmVpbiIsDQogICAgICAgICAgICAgICAiVmljb2RpbiIsDQogICAgICAgICAgICAgICAiV2hpdGUgQnJlYWQiLA0KICAgICAgICAgICAgICAgIldob2xlIFdoZWF0IGFueXRoaW5nIiwNCiAgICAgICAgICAgICAgICJhYnN0YWluZWRfZnJvbV9tX21pbmciLA0KICAgICAgICAgICAgICAgImFub255bW91c19icm93bl9nbG9ic190aGF0X2NvbWVfaW5fYmxhY2tfYW5kX29yYW5nZV93cmFwcGVycyIsDQogICAgICAgICAgICAgICAiYnJva2VuX2dsb3dfc3RpY2siLA0KICAgICAgICAgICAgICAgImRlbnRhbF9wYXJhcGhlbmFsaWEiLA0KICAgICAgICAgICAgICAgImxhcGVsX3BpbnMiLA0KICAgICAgICAgICAgICAgIm1pbnRfbGVhdmVzIiwNCiAgICAgICAgICAgICAgICJwZXJzb25fb2ZfaW50ZXJlc3Rfc2Vhc29uXzNfZHZkX2JveF9zZXRfbm90X2luY2x1ZGluZ19kaXNjXzRfd2l0aF9oaWxhcmlvdXNfb3V0dGFrZXMiLA0KICAgICAgICAgICAgICAgInBldGVyc29uX2JyYW5kX3NpZGV3YWxrX2NoYWxrIikgJT4lDQogIG1ha2VfY2xlYW5fbmFtZXMoKQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KQW5hbHlzaXMgcXVlc3Rpb25zDQpXaGF0IGlzIHRoZSB0b3RhbCBudW1iZXIgb2YgY2FuZHkgcmF0aW5ncyBnaXZlbiBhY3Jvc3MgdGhlIHRocmVlIHllYXJzLiAoTnVtYmVyIG9mIGNhbmR5IHJhdGluZ3MsIG5vdCB0aGUgbnVtYmVyIG9mIHJhdGVycy4gRG9u4oCZdCBjb3VudCBtaXNzaW5nIHZhbHVlcykNCiNqdXN0IGEgbGlzdCBvZiBhbGwgdGhlIGNhbmR5IHJhdGluZ3MNCg0KYGBge3J9DQoNCmNvbWJpbmVkX2RhdGFfbG9uZyAlPiUNCiAgZmlsdGVyKCFpcy5uYShyYXRpbmcpKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9jYW5keV9yYXRpbmdzID0gbigpKQ0KDQpgYGANCg0KV2hhdCB3YXMgdGhlIGF2ZXJhZ2UgYWdlIG9mIHBlb3BsZSB3aG8gYXJlIGdvaW5nIG91dCB0cmljayBvciB0cmVhdGluZz8NCiMgYWdlIGNvbHVtbg0KDQpgYGB7cn0NCg0KY29tYmluZWRfZGF0YV93aWRlICU+JSANCiAgZmlsdGVyKGdvaW5nX291dCA9PSAiWWVzIikgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2FnZSA9IG1lYW4oYWdlLCBuYS5ybSA9IFRSVUUpKQ0KDQpgYGANCg0KDQpXaGF0IHdhcyB0aGUgYXZlcmFnZSBhZ2Ugb2YgcGVvcGxlIHdobyBhcmUgbm90IGdvaW5nIHRyaWNrIG9yIHRyZWF0aW5nPw0KIyBhZ2UgY29sdW1uDQoNCmBgYHtyfQ0KDQpjb21iaW5lZF9kYXRhX3dpZGUgJT4lIA0KICBmaWx0ZXIoZ29pbmdfb3V0ID09ICJObyIpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19hZ2UgPSBtZWFuKGFnZSwgbmEucm0gPSBUUlVFKSkNCg0KDQpgYGANCg0KDQpGb3IgZWFjaCBvZiBqb3ksIGRlc3BhaXIgYW5kIG1laCwgd2hpY2ggY2FuZHkgYmFyIHJlY2VpdmVkIHRoZSBtb3N0IG9mIHRoZXNlIHJhdGluZ3M/DQojIGNhbmR5IHJhdGluZ3MNCg0KYGBge3J9DQoNCmNvbWJpbmVkX2RhdGFfbG9uZyAlPiUNCiAgZ3JvdXBfYnkocmF0aW5nLCBjYW5keV9uYW1lKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIA0KICBzbGljZV9tYXgoY291bnQpIA0KDQpgYGANCg0KDQoNCkhvdyBtYW55IHBlb3BsZSByYXRlZCBTdGFyYnVyc3QgYXMgZGVzcGFpcj8NCiMgc3RhcmJ1cnN0IGNvbHVtbiAoY2FuZHkgY29sdW1ucykNCg0KYGBge3J9DQoNCmNvbWJpbmVkX2RhdGFfbG9uZyAlPiUgDQogIGZpbHRlcihjYW5keV9uYW1lID09ICJzdGFyYnVyc3QiLCByYXRpbmcgPT0gIkRFU1BBSVIiKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkNCiAgDQogIA0KYGBgDQoNCg0KRm9yIHRoZSBuZXh0IHRocmVlIHF1ZXN0aW9ucywgY291bnQgZGVzcGFpciBhcyAtMSwgam95IGFzICsxLCBhbmQgbWVoIGFzIDAuDQoNCg0KDQpXaGF0IHdhcyB0aGUgbW9zdCBwb3B1bGFyIGNhbmR5IGJhciBieSB0aGlzIHJhdGluZyBzeXN0ZW0gZm9yIGVhY2ggZ2VuZGVyIGluIHRoZSBkYXRhc2V0ID8NCiMgY2FuZHkgcmF0aW5ncywgZ2VuZGVyDQoNCmBgYHtyfQ0KDQpjYW5keV9zY29yZWQgPC0gY29tYmluZWRfZGF0YV9sb25nICU+JSANCiAgbXV0YXRlKHNjb3JlID0gY2FzZV93aGVuKA0KICAgIHJhdGluZyA9PSAiSk9ZIiB+IDEsDQogICAgcmF0aW5nID09ICJERVNQQUlSIiB+IC0xLA0KICAgIFRSVUUgfiAwDQogICkpDQoNCmBgYA0KDQpgYGB7cn0NCg0KY2FuZHlfc2NvcmVkICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGdlbmRlcikpICU+JSANCiAgZ3JvdXBfYnkoZ2VuZGVyLCBjYW5keV9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX3Njb3JlID0gc3VtKHNjb3JlKSkgJT4lIA0KICBzbGljZV9tYXgodG90YWxfc2NvcmUpDQogIA0KDQpgYGANCg0KDQpXaGF0IHdhcyB0aGUgbW9zdCBwb3B1bGFyIGNhbmR5IGJhciBpbiBlYWNoIHllYXI/DQojIGRhdGUgb3IgeWVhcg0KDQpgYGB7cn0NCg0KY2FuZHlfc2NvcmVkICU+JSANCiAgZ3JvdXBfYnkoeWVhciwgY2FuZHlfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfc2NvcmUgPSBzdW0oc2NvcmUpKSAlPiUgDQogIHNsaWNlX21heCh0b3RhbF9zY29yZSkNCg0KDQpgYGANCg0KDQpXaGF0IHdhcyB0aGUgbW9zdCBwb3B1bGFyIGNhbmR5IGJhciBieSB0aGlzIHJhdGluZyBmb3IgcGVvcGxlIGluIFVTLCBDYW5hZGEsIFVLLCBhbmQgYWxsIG90aGVyIGNvdW50cmllcz8NCiMgY291bnRyaWVzDQoNCmBgYHtyfQ0KDQpjYW5keV9zY29yZWQgJT4lDQogIGZpbHRlcihjb3VudHJ5ID09IGMoIlVTQSIsICJDYW5hZGEiLCAiVUsiLCAiT3RoZXIiKSkgJT4lIA0KICBncm91cF9ieShjb3VudHJ5LCBjYW5keV9uYW1lKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9zY29yZSA9IHN1bShzY29yZSkpICU+JSANCiAgc2xpY2VfbWF4KHRvdGFsX3Njb3JlKQ0KDQpgYGANCg0K